﻿
using System.Collections.ObjectModel;
using System.Linq;
using Gwn.Library.MvpVm.Entities;
using Gwn.Library.MvpVm.Interfaces;
using Microsoft.Practices.Prism.Commands;

namespace Gwn.Library.MvpVm.ViewModels
{
    /// <summary>
    /// User command view model
    /// </summary>
    public class UserCommandViewModel : UserViewModel, IViewModelCommand
    {
        #region Fields
        private bool _isAdding;
        private bool _isEditing;
        private User _selectedUser;
        private string _statusMessage;
        private DelegateCommand<object> _command;
        private int _selectedIndex;
        private ObservableCollection<User> _userList;
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the command.
        /// </summary>
        /// <value>The command.</value>
        public DelegateCommand<object> Command
        {
            get { return _command; }
            set
            {
                _command = value;
                OnPropertyChanged("Command");
            }
        }

        /// <summary>
        /// Gets or sets the user list.
        /// </summary>
        /// <value>The user list.</value>
        public ObservableCollection<User> UserList
        {
            get { return _userList; }
            set
            {
                // Force a refresh
                _userList = null;
                OnPropertyChanged("UserList");
                _userList = value;
                OnPropertyChanged("UserList");
            }
        }

        /// <summary>
        /// Gets or sets the selected user.
        /// </summary>
        /// <value>The selected user.</value>
        public User SelectedUser
        {
            get { return _selectedUser; }
            set
            {
                _selectedUser = value;

                // Transfer selected item to view model
                if (value != null)
                {
                    FirstName = value.FirstName;
                    LastName = value.LastName;
                    MiddleName = value.MiddleName;
                    DateOfBirth = value.DateOfBirth;
                }
                OnPropertyChanged("SelectedUser");
            }
        }
        
        /// <summary>
        /// Gets or sets the state of the add edit undo delete command.
        /// </summary>
        /// <value>The state of the add edit undo delete command.</value>
        public object AddEditUndoDeleteCommandState { get; set; }

        /// <summary>
        /// Gets or sets the cached user.
        /// </summary>
        /// <value>The cached user.</value>
        public string CachedUser { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is adding.
        /// </summary>
        /// <value><c>true</c> if this instance is adding; otherwise, <c>false</c>.</value>
        public bool IsAdding
        {
            get { return _isAdding; }
            set
            {
                _isAdding = value;
                OnPropertyChanged("IsAdding");
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is editing.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is editing; otherwise, <c>false</c>.
        /// </value>
        public bool IsEditing
        {
            get { return _isEditing; }
            set
            {
                _isEditing = value;
                OnPropertyChanged("IsEditing");
            }
        }

        /// <summary>
        /// Gets or sets the index of the selected.
        /// </summary>
        /// <value>The index of the selected.</value>
        public int SelectedIndex
        {
            get { return _selectedIndex; }
            set
            {
                _selectedIndex = value;
                OnPropertyChanged("SelectedIndex");
            }
        }

        /// <summary>
        /// Gets or sets the status message.
        /// </summary>
        /// <value>The status message.</value>
        public string StatusMessage
        {
            get { return _statusMessage; }
            set
            {
                _statusMessage = value;
                OnPropertyChanged("StatusMessage");
            }
        }
        #endregion 

        #region Methods that are specific to this ViewModel and reusable across modules 
        /// <summary>
        /// Deletes the user from list.
        /// </summary>
        /// <param name="record">The record.</param>
        public void DeleteUserFromViewModelList(User record)
        {
            var user = UserList.FirstOrDefault(p => p.Id == record.Id);
            if (user != null)
                UserList.Remove(record);
            
            // Force a refresh
            UserList = UserList;
            SelectedUser = UserList.FirstOrDefault();
            
        }

        /// <summary>
        /// Creates the user from view model.
        /// </summary>
        /// <returns></returns>
        public User CreateUserFromViewModel()
        {
            if (SelectedUser == null)
                return new User();

            // Transfer from view model to domain object
            var user = new User
            {
                Id = SelectedUser.Id,
                FirstName = this.FirstName,
                LastName = this.LastName,
                DateOfBirth = this.DateOfBirth,
                MiddleName = this.MiddleName
            };
            return user;
        }

        /// <summary>
        /// Updates the view model from new user record.
        /// </summary>
        /// <param name="record">The record.</param>
        public void UpdateViewModelFromNewUserRecord(User record)
        {
            // Update our reference
            var user = SelectedUser;
            SelectedUser.Id = record.Id;
            SelectedUser.FirstName = record.FirstName;
            SelectedUser.LastName = record.LastName;
            SelectedUser.MiddleName = record.MiddleName;
            SelectedUser.DateOfBirth = record.DateOfBirth;

            // Force refresh
            SelectedUser = user;

            UserList = UserList;
        }
        #endregion 

    }
}
